import LayVmodelBase from "./LayVmodelBase.js"
import { logger, tools, runtime } from "./tools.js";

/**Layui 表格模型 */
class LayTableVmodel extends LayVmodelBase {
    tableInstance = null;
    innerTable = null;
    innerBody = null;

    constructor(elem, config) {
        super(elem);
        this.config = config;
        this.ensureFilter();
    }

    getCell(index, key) {
        let tr = $(this.innerTable).find("tr[data-index='" + index + "']");
        let cell = tr.find("td[data-field='" + key + "'] > .layui-table-cell")[0];
        return cell;
    }

    getTr(index) {
        let tr = $(this.innerTable).find("tr[data-index='" + index + "']");
        return tr;
    }

    /**[override] */
    onDisabledChange(disabled) {
        return;
    }

    viewModelInit() {
        this.vm.data = ko.observableArray([]);
    }

    //触发视图更新
    triggerUpdate(record, keys) {
        let table = tools.laymod('table');
        let tr = this.getTr(record[table.config.indexName]);
        if (!tr) return;
        let span = $(tr).find(".vlaytable-updater")[0];
        if (!span) return;
        if (keys.length == 0) return;

        span.changeParams = {
            fields: keys,
            eventType: "update"
        }
        $(span).trigger("dblclick");
        span.changeParams = null;
    }

    //触发视图删除
    triggerDelete(record) {
        let table = tools.laymod('table');
        let tr = this.getTr(record[table.config.indexName]);
        if (!tr) return;
        let span = $(tr).find(".vlaytable-updater")[0];
        if (!span) return;
        span.changeParams = {
            eventType: "delete"
        }
        $(span).trigger("dblclick");
        span.changeParams = null;
    }

    dataProxy() {
        let tis = this;
        let cfg = tis.config;
        let recrods = this.vm.data();
        for (let i = 0; i < recrods.length; i++) {
            let record = recrods[i];
            for (let key in record) {
                let value = record[key];
                //如果是function，不处理
                if (typeof value == "function") continue;
                tools.hook.defineKidnapAutoProp(record, key, value, {
                    beforeSet: function (args) {
                    },
                    afterSet: function (args) {
                        tis.triggerUpdate(record, [key]);
                    },
                    beforeGet: function (args) {
                    }
                })
            }
        }
    }

    /**[override] */
    init() {
        if (!super.init()) return;

        let tis = this;
        let cfg = tis.config;
        let elem = tis.element;
        let vm = tis.vm;
        let table = tools.laymod('table');

        if (!cfg.cols) throw new Error("LayTableVmodel: cols 是必须的配置项");

        cfg.elem = elem;
        let initData = this.vm.data();
        if (initData) {
            cfg.data = initData;
        }
        this.vm.data(cfg.data || []);

        //初始化数据
        tis.dataProxy();

        //订阅数据变化
        vm.data.subscribe(function (changes) {
            if (!changes) return;
            if (changes.length == 0) return;

            var added = changes.filter(f => f.status == "added");
            var deleted = changes.filter(f => f.status == "deleted");

            if (added.length > 0) {
                tis.dataProxy();
                if (layui.v < '2.8.5') {
                    table.reloadData(cfg.id, {
                        data: vm.data()
                    })
                } else {
                    table.cache[cfg.id] = vm.data();
                    table.renderData(cfg.id);
                }
                return; //重新加载后无需执行后续操作
            }

            //处理被删除的数据
            for (let i = 0; i < deleted.length; i++) {
                let change = deleted[i];
                let index = change.index;
                let record = change.value;
                let status = change.status;
                tis.triggerDelete(record);
            }

        }, null, "arrayChange");

        //订阅引用变化
        vm.data.subscribe(function (newValue) {
            if (newValue === vm.data()) return;
            //当赋值新数组时，重新初始化数据
            tis.dataProxy();
            if (layui.v < '2.8.5') {
                table.reloadData(cfg.id, {
                    data: vm.data()
                })
            } else {
                table.cache[cfg.id] = vm.data();
                table.renderData(cfg.id);
            }
        }, null, "change");

        //创建一个隐藏列
        cfg.cols[0].push({
            //fixed: "",
            //field: "laytable_hidden_col",
            title: "",
            hide: true,
            templet: function (d) {
                return `<span class="vlaytable-updater" lay-event="vlaytable-changeEvent"></span>`;
            }
        });

        //处理视图更新
        table.on('toolDouble(' + tis.layFilter + ')', function (obj) {
            let event = obj.event;
            let span = $(obj.tr).find(".vlaytable-updater")[0];
            if (event !== "vlaytable-changeEvent") return;

            let params = span.changeParams;
            if (!params) return;

            if (params.eventType == "delete") {
                //删除数据
                obj.del();
            }
            else if (params.eventType == "update") {
                var fields = params.fields;
                var updateData = {};
                //更新数据
                for (let i = 0; i < fields.length; i++) {
                    let field = fields[i];
                    updateData[field] = obj.data[field];
                }
                //更新数据
                obj.update(updateData);
            }
        });

        this.tableInstance = table.render(cfg);
        this.innerTable = $(elem).next(".layui-table-view").find(".layui-table-body .layui-table")[0];
        this.innerBody = $(elem).next(".layui-table-view").find(".layui-table-body")[0];
    }
}


export default LayTableVmodel;